<?php

namespace App\Repository;

use App\Consts\GlobalConst;
use App\Consts\GlobalNoteConst;
use App\Models\IndexNote;
use App\Models\IndexSearchNote;
use App\Models\Select\NoteSelect;
use App\Models\SysNote;
use App\Models\SysNoteContent;
use App\Models\SysNoteImg;
use App\Models\SysNoteLine;
use App\Models\SysNoteSelected;
use Illuminate\Database\Eloquent\Builder;

/**
 * @package App\Repository
 * @see NoteRepository
 */
class NoteRepository extends BaseRepository
{
    public function getSearchNoteList($searchParams)
    {
        $query = IndexSearchNote::getInstance()
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD)
            ->whereIn('type', [GlobalNoteConst::TYPE_ARTICLE_NOTE, GlobalNoteConst::TYPE_LINE_NOTE]);

        if (!empty($searchParams['keywords_note'])) {
            $query->where('content', 'like', '%' . $searchParams['keywords_note'] . '%');
        }

        if (!empty($searchParams['last_id'])) {
            $id = SysNote::getInstance($searchParams['last_id'])
                ->select(['id'])
                ->where('note_id', $searchParams['last_id'])
                ->value('id');
            $query->where('id', '<', $id);
        }

        $query->orderByDesc('created_at');
        $query->orderByDesc('id');

        return $this->setPagination($query);
    }

    public function getLineNoteList($searchParams)
    {
        $query = IndexNote::getInstance()
            ->where('user_id', $searchParams['user_id'])
            ->where('article_id', $searchParams['article_id'])
            ->where('start_index', '>=', $searchParams['start_index'])
            ->where('end_index', '<=', $searchParams['end_index'])
            ->whereIn('type', [GlobalNoteConst::TYPE_ARTICLE_NOTE, GlobalNoteConst::TYPE_LINE_NOTE])
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD)
            ->where('is_view', GlobalNoteConst::IS_VIEW);

        if (!empty($searchParams['last_id'])) {
            $operator = $searchParams['order'] == SORT_ASC ? '>' : '<';
            $query->where('note_id', $operator, $searchParams['last_id']);
        }

        $query->orderByDesc('id');
        $searchParams['order'] == SORT_ASC ? $query->orderBy('created_at') : $query->orderByDesc('created_at');

        return $this->setPagination($query);
    }

    public function getArticleNoteList($searchParams)
    {
        $provider = IndexNote::getInstance()
            ->where('article_id', $searchParams['article_id'])
            ->whereIn('type', [GlobalNoteConst::TYPE_ARTICLE_NOTE, GlobalNoteConst::TYPE_LINE_NOTE])
            ->where('is_public', GlobalNoteConst::IS_PUBLIC)
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD)
            ->where('is_view', GlobalNoteConst::IS_VIEW);
        if ($searchParams['tab'] == GlobalNoteConst::TAB_TYPE_MY) {
            $provider->where('user_id', $searchParams['user_id']);
        }
        if (!empty($searchParams['last_id'])) {
            $operator = $searchParams['order'] == SORT_ASC ? '>' : '<';
            $provider->where('note_id', $operator, $searchParams['last_id']);
        }

        $provider->orWhere(function ($query) use ($searchParams) {
            $query->where('article_id', $searchParams['article_id'])
                ->where('user_id', $searchParams['user_id'])
                ->whereIn('type', [GlobalNoteConst::TYPE_ARTICLE_NOTE, GlobalNoteConst::TYPE_LINE_NOTE])
                ->whereIn('is_public', [GlobalNoteConst::IS_PUBLIC, GlobalNoteConst::IS_NOT_PUBLIC])
                ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
                ->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD)
                ->where('is_view', GlobalNoteConst::IS_VIEW);
            if (!empty($searchParams['last_id'])) {
                $operator = $searchParams['order'] == SORT_ASC ? '>' : '<';
                $query->where('note_id', $operator, $searchParams['last_id']);
            }
        });

        $provider->orderByDesc('id');
        $searchParams['order'] == SORT_ASC ? $provider->orderBy('created_at') : $provider->orderByDesc('created_at');


        return $this->setPagination($provider);
    }

    /**
     * @param $searchParams
     * @return Builder
     */
    public function getUserNoteList($searchParams)
    {
        $isPublic = $searchParams['user_id'] == $searchParams['current_user_id'] ?
            [GlobalNoteConst::IS_NOT_PUBLIC, GlobalNoteConst::IS_PUBLIC] :
            [GlobalNoteConst::IS_PUBLIC];

        $query = IndexNote::getInstance()
            ->where('user_id', $searchParams['user_id'])
            ->whereIn('is_public', $isPublic)
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD)
            ->where('is_view', GlobalNoteConst::IS_VIEW)
            ->whereIn('type', [GlobalNoteConst::TYPE_ARTICLE_NOTE, GlobalNoteConst::TYPE_LINE_NOTE]);

        if (!empty($searchParams['ignore'])) {
            $query->where('note_id', '<>', $searchParams['ignore']);
        }

        if (!empty($searchParams['last_id'])) {
            $noteId = IndexNote::getInstance()
                ->select(['note_id'])
                ->where('note_id', $searchParams['last_id'])
                ->value('note_id');
            $query->where('note_id', '<', $noteId);
        }

        $query->orderByDesc('created_at');

        return $this->setPagination($query);
    }

    /**
     * @param $loadData
     * @return SysNote|Builder|\Illuminate\Database\Eloquent\Model|bool
     */
    public function create($loadData)
    {
        $note = SysNote::getModel($loadData['note_id'])->create($loadData);
        return $note ?: false;
    }

    /**
     * @param $loadData
     * @return IndexNote|bool|Builder|\Illuminate\Database\Eloquent\Model|bool
     */
    public function createIndex($loadData)
    {
        $indexNote = IndexNote::getModel()->create($loadData);
        $indexSearchNote = IndexSearchNote::getModel()->create($loadData);
        return $indexNote && $indexSearchNote ? $indexNote : false;
    }

    /**
     * @param $loadData
     * @return SysNoteContent|Builder|\Illuminate\Database\Eloquent\Model|bool
     */
    public function createNoteContent($loadData)
    {
        $noteContent = SysNoteContent::getModel($loadData['note_id'])->create($loadData);
        return $noteContent ?: false;
    }

    /**
     * @param $loadData
     * @return SysNoteSelected|Builder|\Illuminate\Database\Eloquent\Model|bool
     */
    public function createNoteSelected($loadData)
    {
        $noteSelected = SysNoteSelected::getModel($loadData['note_id'])->create($loadData);
        return $noteSelected ?: false;
    }

    /**
     * @param $loadData
     * @return SysNoteLine|Builder|\Illuminate\Database\Eloquent\Model|bool
     */
    public function createNoteLine($loadData)
    {
        $noteLine = SysNoteLine::getModel($loadData['note_id'])->create($loadData);
        return $noteLine ?: false;
    }

    /**
     * @param $noteId
     * @return SysNote|bool|Builder|object|null
     */
    public function delNoteById($noteId)
    {
        IndexNote::getModel()
            ->where('note_id', $noteId)
            ->update([
                'is_deleted' => GlobalConst::IS_DELETED,
                'is_view' => GlobalNoteConst::IS_NOT_VIEW,
            ]);
        IndexSearchNote::getModel()
            ->where('note_id', $noteId)
            ->update(['is_deleted' => GlobalConst::IS_DELETED]);
        $note = $this->getNoteById($noteId);
        if (!$note) {
            return false;
        }
        $note->is_deleted = GlobalConst::IS_DELETED;
        $note->is_view = GlobalNoteConst::IS_NOT_VIEW;
        $note->save();
        return $note;
    }

    /**
     * @param SysNote $note
     * @param $loadData
     * @return bool|SysNote
     */
    public function edit(SysNote $note, $loadData)
    {
        $note->update($loadData);
        IndexNote::getModel()
            ->where('note_id', $note->note_id)
            ->update(['is_public' => $note->is_public]);
        IndexSearchNote::getModel()
            ->where('note_id', $note->note_id)
            ->update(['is_public' => $note->is_public]);
        return $note ?: false;
    }

    /**
     * 通过分表数，获取笔记基础信息
     * @param $tableIndex
     * @param $noteId
     * @param string $selectScene
     * @return SysNote[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model[]
     */
    public function getNoteByTableCount($tableIndex, $noteId, $selectScene = NoteSelect::SELF_LIST)
    {
        $tableName = SysNote::getTableNameByTableIndex($tableIndex);
        $noteId = (array)$noteId;

        return SysNote::setTableName($tableName)
            ->select(NoteSelect::getSelects($selectScene))
            ->whereIn('note_id', $noteId)
            ->get();
    }

    /**
     * 通过分表数，获取笔记内容
     * @param $tableIndex
     * @param $noteId
     * @param $selects
     * @return SysNoteSelected[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model[]
     */
    public function getNoteContentByTableCount($tableIndex, $noteId, $selects = ['*'])
    {
        $tableName = SysNoteContent::getTableNameByTableIndex($tableIndex);
        $noteId = (array)$noteId;

        return SysNoteContent::setTableName($tableName)
            ->select($selects)
            ->whereIn('note_id', $noteId)
            ->get();
    }

    /**
     * 通过分表数，获取笔记文章节选
     * @param $tableIndex
     * @param $noteId
     * @param $selects
     * @return SysNoteSelected[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model[]
     */
    public function getNoteSelectedByTableCount($tableIndex, $noteId, $selects = ['*'])
    {
        $tableName = SysNoteSelected::getTableNameByTableIndex($tableIndex);
        $noteId = (array)$noteId;

        return SysNoteSelected::setTableName($tableName)
            ->select($selects)
            ->whereIn('note_id', $noteId)
            ->get();
    }

    public function getNoteImgByTableCount($tableCount, $noteId)
    {
        return SysNoteImg::setTableNameByTableCount($tableCount)
            ->whereIn('note_id', (array)$noteId)
            ->get();
    }

    public function getNoteLineByTableCount($tableCount, $noteId)
    {
        return SysNoteLine::setTableNameByTableCount($tableCount)
            ->whereIn('note_id', (array)$noteId)
            ->get();
    }

    /**
     * 获取用户某文章的划线笔记
     * @param $userId
     * @param $articleId
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getLineNotesByUserIdAndArticleId($userId, $articleId)
    {
        return IndexNote::getInstance()
            ->select(['note_id', 'start_index', 'end_index'])
            ->where('user_id', $userId)
            ->where('article_id', $articleId)
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->where('is_shield', GlobalNoteConst::IS_NOT_SHIELD)
            ->get();
    }

    /**
     * 通过笔记ID获取笔记
     * @param $noteId
     * @param string $selectScene
     * @return \Illuminate\Database\Eloquent\Builder|SysNote|object|null
     */
    public function getNoteByNoteId($noteId, $selectScene = NoteSelect::BASE_INFO)
    {
        return SysNote::getInstance($noteId)
            ->select(NoteSelect::getSelects($selectScene))
            ->where('note_id', $noteId)
            ->first();
    }

    /**
     * @param $noteId
     * @param string $selectScene
     * @return SysNote|Builder|object|null
     */
    public function getNoteById($noteId, $selectScene = NoteSelect::BASE_INFO)
    {
        return $this->getNoteByNoteId($noteId, $selectScene);
    }

}
